package com.mrd.modules.attachment;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerGroup;
import org.csource.fastdfs.TrackerServer;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import com.mrd.base.utils.FileException;
import com.mrd.base.utils.FileUtils;
import com.mrd.base.utils.JsonUtils;

/**
 * fastdfs附件管理类 Created by han
 */
// @Component("fastDFSAttachment")
public class FastDFSAttachmentImpl implements AttachmentService {

  /**
   * FastDFS服务器地址
   */
  private String hostName;
  /**
   * 端口
   */
  private Integer port;
  /**
   * 编码
   */
  private String charset;
  /**
   * 超时时间
   */
  private Integer networkTimeout;

  private String http;

  public String getHttp() {
    return http;
  }

  public void setHttp(String http) {
    this.http = http;
  }

  public String getHostName() {
    return hostName;
  }

  public void setHostName(String hostName) {
    this.hostName = hostName;
  }

  public Integer getPort() {
    return port;
  }

  public void setPort(Integer port) {
    this.port = port;
  }

  public String getCharset() {
    return charset;
  }

  public void setCharset(String charset) {
    this.charset = charset;
  }

  public Integer getNetworkTimeout() {
    return networkTimeout;
  }

  public void setNetworkTimeout(Integer networkTimeout) {
    this.networkTimeout = networkTimeout;
  }

  private TrackerServer trackerServer;

  private StorageServer storageServer;

  private StorageClient storageClient;

  public TrackerServer getTrackerServer() {
    return trackerServer;
  }

  public void setTrackerServer(TrackerServer trackerServer) {
    this.trackerServer = trackerServer;
  }

  public StorageServer getStorageServer() {
    return storageServer;
  }

  public void setStorageServer(StorageServer storageServer) {
    this.storageServer = storageServer;
  }

  public StorageClient getStorageClient() {
    return storageClient;
  }

  public void setStorageClient(StorageClient storageClient) {
    this.storageClient = storageClient;
  }

  private void init() {
    ClientGlobal.setG_charset(charset);
    ClientGlobal.setG_network_timeout(networkTimeout);
    TrackerGroup tg =
        new TrackerGroup(new InetSocketAddress[] {new InetSocketAddress(hostName, port)});
    TrackerClient tc = new TrackerClient(tg);
    try {
      trackerServer = tc.getConnection();
    } catch (IOException e) {
      e.printStackTrace();
      return;
    }
    if (trackerServer != null) {
      try {
        storageServer = tc.getStoreStorage(trackerServer);
      } catch (IOException e) {
        e.printStackTrace();
        return;
      }
    }
    if (storageServer != null) {
      storageClient = new StorageClient(trackerServer, storageServer);
    }
  }

  @Override
  public String upload(MultipartFile multipartFile, String fileName) throws IOException {
    String name = multipartFile.getOriginalFilename();
    String type = FileUtils.getFileType(name).toLowerCase();
    return this.upload(multipartFile.getInputStream(), name, type);
  }

  @Override
  public String upload(InputStream inputStream, String fileName, String type) {
    this.init();
    Assert.notNull(storageClient, "文件服务器没有创建成功！");
    byte[] data = null;
    try {
      data = FileUtils.readInputStream(inputStream);
    } catch (IOException e) {
      e.printStackTrace();
      try {
        throw new FileException(e.getMessage());
      } catch (FileException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }
    }
    NameValuePair[] metaList = null;
    /*
     * if(StringUtils.hasText(fileName)){ metaList=new NameValuePair[1]; metaList[0] = new
     * NameValuePair("fileName", fileName); }
     */
    String[] sArray = null;
    try {
      sArray = storageClient.upload_appender_file(data, type, metaList);
    } catch (IOException e) {
      e.printStackTrace();
      try {
        throw new FileException(e.getMessage());
      } catch (FileException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }
    } catch (MyException e) {
      e.printStackTrace();
      try {
        throw new FileException(e.getMessage());
      } catch (FileException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }
    } finally {
      this.close();
    }
    StringBuffer sb = new StringBuffer();
    sb.append(sArray[0]);
    sb.append("-");
    sb.append(sArray[1]);
    return sb.toString();
  }

  @Override
  public String getPath() {
    return http;
  }

  @Override
  public File download(String path) {
    String[] sArray = path.split("-");
    if (sArray.length == 2) {
      StringBuffer url = new StringBuffer(http);
      url.append("/");
      url.append(sArray[0]);
      url.append("/");
      url.append(sArray[1]);
      try {
        int i = sArray[1].lastIndexOf("/");
        String name = sArray[1].substring(i + 1, sArray[1].length());
        File file = FileUtils.urlToFile(url.toString(), name);
        return file;
      } catch (Exception e) {
        e.printStackTrace();
      }

    }
    return null;
  }

  @Override
  public void download(String path, String fileName, HttpServletResponse response) {
    String[] sArray = path.split("-");
    if (sArray.length == 2) {
      StringBuffer url = new StringBuffer(http);
      url.append("/");
      url.append(sArray[0]);
      url.append("/");
      url.append(sArray[1]);
      try {
        response.sendRedirect(url.toString());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  @Override
  public String upload(File file, String fileName, String type) throws Exception {
    InputStream in = new FileInputStream(file);
    return this.upload(in, fileName, type);
  }

  @Override
  public void delete(String path) {
    this.init();
    Assert.notNull(storageClient, "文件服务器没有创建成功！");
    List list = JsonUtils.jsonToList(path, String.class);
    if (list.size() == 2) {
      String groupName = (String) list.get(0);
      String remoteFilename = (String) list.get(1);
      try {
        storageClient.delete_file(groupName, remoteFilename);
      } catch (IOException e) {
        e.printStackTrace();
        try {
          throw new FileException(e.getMessage());
        } catch (FileException e1) {
          // TODO Auto-generated catch block
          e1.printStackTrace();
        }
      } catch (MyException e) {
        e.printStackTrace();
        try {
          throw new FileException(e.getMessage());
        } catch (FileException e1) {
          // TODO Auto-generated catch block
          e1.printStackTrace();
        }
      } finally {
        this.close();
      }
    }
  }

  private void close() {
    if (trackerServer != null) {
      try {
        trackerServer.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
      trackerServer = null;
    }
    if (storageServer != null) {
      try {
        storageServer.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
      storageServer = null;
    }
    storageClient = null;
  }
}
